//=============================================================================
///	Hash table
//=============================================================================

#ifndef	__HASHTABLE_H__
#define	__HASHTABLE_H__

#include <stdio.h>		// for size_t

#ifdef __cplusplus
extern "C" {
#endif

// hash table

typedef struct HashVTbl {
	void* (*alloc)(size_t);
	void (*free)(void*);
	unsigned int (*hash)(const void*);
	int (*check)(const void* entry, const void* key);
} HashVTbl;

typedef struct HashEntry {
	struct HashEntry* next;
	unsigned int hash;
	const void* key;	///< pointer to key
	void* val;			///< pointer to value
} HashEntry;

typedef struct {
	const struct HashVTbl* vtbl;
	HashEntry** buf;
	size_t bufsiz;
} HashTable;


void ht_init(HashTable* ht, const HashVTbl* vtbl);
void ht_term(HashTable* ht);
void ht_clear_all(HashTable* ht);
void ht_resize(HashTable* ht, size_t siz);
HashEntry* ht_find(HashTable* ht, const void* key);
void ht_add_direct(HashTable* ht, const void* key, void* val);
int ht_remove(HashTable* ht, const void* key);


// hash entry iterator
typedef struct {
	HashTable* ht;
	int idx;
	HashEntry* p;
} HashIterator;

HashEntry* ht_begin(HashIterator* it, HashTable* ht);
HashEntry* ht_next(HashIterator* it);


void ht_get_info(HashTable* ht, int* psize, int* pelem, int* pcollide, int* pmaxcollide);


#ifdef __cplusplus
} // extern "C"
#endif

#endif
